﻿Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO

Public Class ScreenCapture

    'Public Function CaptureScreen() As Image
    '    Return CaptureWindow(User32.GetDesktopWindow())
    'End Function
    Public Function CaptureScreenAsPNG() As Byte()
        Return CaptureScreen(ImageFormat.Png)
    End Function

    Private Function CaptureScreen(ByVal imageFormat As ImageFormat) As Byte()
        Dim bmp = CaptureWindow(User32.GetDesktopWindow())
        Dim imageBytes As Byte() = Nothing

        Using ms As New MemoryStream
            bmp.Save(ms, imageFormat)
            imageBytes = ms.ToArray()
        End Using

        Return imageBytes
    End Function

    Private Function CaptureWindow(ByVal handle As IntPtr) As Bitmap
        ' get te hDC of the target window
        Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
        ' get the size
        Dim windowRect As New User32.RECT()
        User32.GetWindowRect(handle, windowRect)
        Dim width As Integer = windowRect.right - windowRect.left
        Dim height As Integer = windowRect.bottom - windowRect.top
        ' create a device context we can copy to
        Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
        ' create a bitmap we can copy it to,
        ' using GetDeviceCaps to get the width/height
        Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
        ' select the bitmap object
        Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
        ' bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, _
            0, 0, GDI32.SRCCOPY)
        ' restore selection
        GDI32.SelectObject(hdcDest, hOld)
        ' clean up 
        GDI32.DeleteDC(hdcDest)
        User32.ReleaseDC(handle, hdcSrc)
        ' get a .NET image object for it
        'Dim img As Image = Image.FromHbitmap(hBitmap)
        Dim img = Image.FromHbitmap(hBitmap)
        ' free up the Bitmap object
        GDI32.DeleteObject(hBitmap)
        Return img
    End Function

    'Public Sub CaptureWindowToFile(handle As IntPtr, filename As String, format As ImageFormat)
    '    Dim img As Image = CaptureWindow(handle)
    '    img.Save(filename, format)
    'End Sub

    'Public Sub CaptureScreenToFile(filename As String, format As ImageFormat)
    '    Dim img As Image = CaptureScreen()
    '    img.Save(filename, format)
    'End Sub

    Private Class GDI32

        Public Const SRCCOPY As Integer = &HCC0020
        <DllImport("gdi32.dll")> _
        Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, _
        ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean
        End Function
        <DllImport("gdi32.dll")> _
        Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
        End Function
        <DllImport("gdi32.dll")> _
        Public Shared Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
        End Function
        <DllImport("gdi32.dll")> _
        Public Shared Function DeleteDC(ByVal hDC As IntPtr) As Boolean
        End Function
        <DllImport("gdi32.dll")> _
        Public Shared Function DeleteObject(ByVal hObject As IntPtr) As Boolean
        End Function
        <DllImport("gdi32.dll")> _
        Public Shared Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
        End Function
    End Class

    Private Class User32

        <StructLayout(LayoutKind.Sequential)>
        Public Structure RECT
            Public left As Integer
            Public top As Integer
            Public right As Integer
            Public bottom As Integer
        End Structure

        <DllImport("user32.dll")>
        Public Shared Function GetDesktopWindow() As IntPtr
        End Function
        <DllImport("user32.dll")>
        Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
        End Function
    End Class

End Class
